package com.qkjia.srb.base.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 *  @author 赵乾坤
 *  @since 2021-11-06 22:07
 */
@Configuration//配置类
public class RedisConfig {

    //    @Autowired
    //    private StringRedisTemplate stringRedisTemplate;  //对字符串支持比较友好,不能存储对象
    //    @Resource
    //    private RedisTemplate redisTemplate;  //存储对象

    /**
     * 使用json序列化方式
     * @param factory
     * @return
     */
    /**
     * 存储 String Value 连接方式
     * @param factory     连接工厂创建基于Lettuce 的连接。
     * @return
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory factory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        // 设置连接池工厂
        redisTemplate.setConnectionFactory(factory);
        // 设置key的序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());

        // 解决value的序列化方式
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        // 序列化时将类的数据类型存入json，以便反序列化的时候转换成正确的类型
        ObjectMapper objectMapper = new ObjectMapper();

        // 将当前对象的数据类型也存入序列化的结果字符串中  相当于调用的便捷方法
//        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);

        // 解决jackson2无法反序列化LocalDateTime的问题
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());

        // 设置此视图的ObjectMapper 。 如果未设置，则使用默认的ObjectMapper 。
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // 设置此模板要使用的值序列化程序。 默认为getDefaultSerializer() 。
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        return redisTemplate;
    }
}